home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / rdkybd.zip / RDKYBD.PAS < prev    next >
Pascal/Delphi Source File  |  1993-01-04  |  19KB  |  478 lines

  1.  
  2. {$R-,S-,T-,V-}
  3. { Turbo Pascal 4.0 unit of keyboard routines to read and validate byte/
  4.   integer/real number/string/password entry with cursor key editing.
  5.   The enter key does not advance the cursor to the next line.  Use GotoXY
  6.   before call to display entry at a specific screen position.  Use Writeln
  7.   after the call to advance the cursor to the next line when using a scrolling
  8.   display.  Set background and text colors with TextBackground and TextColor.}
  9.  
  10. { John Haluska, CIS 74000,1106 }
  11.  
  12. unit Rdkybd;
  13.  
  14. interface
  15.  
  16. uses Crt;
  17.  
  18. var
  19.   ErrorToneEnb : boolean;       {Enables (true) or disables (false) ErrorTone }
  20.  
  21. procedure  ErrorTone;
  22. procedure  Password(var P : string);
  23. procedure  ReadByte(var N : byte);
  24. procedure  ReadIntgr(var N : integer);
  25. procedure  ReadLongInt(var N : longint);
  26. procedure  ReadByteMinMax(Min,Max : byte; var N : byte);
  27. procedure  ReadIntgrMinMax(Min,Max : integer; var N : integer);
  28. procedure  ReadLongIntMinMax(Min,Max : longint; var N : longint);
  29. procedure  ReadReal(var N : real);
  30. procedure  ReadRealMinMax(Min,Max : real; var N : real);
  31. procedure  ReadString (var S : string);
  32.  
  33. implementation
  34.  
  35. {-----------------------------------------------------------------------------}
  36. { ErrorTone generates a 120 Hz tone for .1 second if unit global variable
  37.   ErrorToneEnb is true (default).  The caller can set ErrorToneEnb := False
  38.   to disable ErrorTone. }
  39.  
  40. procedure ErrorTone;
  41.           {Requires unit global variable ErrorToneEnb}
  42.   begin
  43.     if ErrorToneEnb then
  44.       begin
  45.         Sound(120);  Delay(100);  NoSound;
  46.       end;
  47.   end; {ErrorTone}
  48. {-----------------------------------------------------------------------------}
  49. { Password reads a string of characters and echos the entered characters as
  50.   asterisks to the display.  The Bksp and Esc keys edit the input.  The Enter
  51.   key terminates the input and does not advance the cursor to the next line. }
  52.  
  53. procedure Password(var P : string);
  54.          { Requires procedure ErrorTone }
  55.   var
  56.     C     : char;
  57.     I,X,Y : byte;
  58.   begin
  59.     P[0] := #0;
  60.     X := WhereX; Y := WhereY;
  61.     repeat
  62.       C := ReadKey;
  63.       case C of
  64.         #32..#127  : begin
  65.                        P := P + C;
  66.                        Write('*');
  67.                      end;
  68.         #8         : begin                        {Backspace}
  69.                        if Length(P) > 0 then
  70.                          begin
  71.                            Delete(P,Length(P),1);
  72.                            Write(#8,' ',#8);
  73.                          end
  74.                        else ErrorTone;
  75.                      end;
  76.         #27        : begin                         {Escape}
  77.                        GotoXY(X,Y);
  78.                        for I := 1 to Length(P) do Write(' ');
  79.                        GotoXY(X,Y);
  80.                        P[0] := #0;
  81.                      end;
  82.         #13        : ;                             {CR}
  83.         #0         : begin                      {Extended Key}
  84.                        C := ReadKey;  ErrorTone;
  85.                      end;
  86.         else ErrorTone;
  87.       end;
  88.     until C = #13;                                 {CR}
  89.   end {Password};
  90. {-----------------------------------------------------------------------------}
  91. { ReadByte, ReadIntgr, and ReadLongInt are similar to the corresponding MinMax
  92.   procedures except these procedures will accept any valid corresponding byte,
  93.   integer, or longinteger.  Example: ReadIntgr(N) will erase the input if
  94.   35000 is entered. }
  95.  
  96. procedure ReadByte(var N : byte);
  97.          { Requires procedure ReadLongIntMinMax }
  98.   var  M : longint;
  99.   begin
  100.     ReadLongIntMinMax(0,255,M);
  101.     N := M;
  102.   end; {ReadByte}
  103.  
  104. procedure ReadIntgr(var N : integer);
  105.          { Requires procedure ReadLongIntMinMax }
  106.   var  M : longint;
  107.   begin
  108.     ReadLongIntMinMax(-32768,32767,M);
  109.     N := M;
  110.   end; {ReadIntgr}
  111.  
  112. procedure ReadLongInt(var N : longint);
  113.          { Requires procedure ReadLongIntMinMax }
  114.   begin
  115.     ReadLongIntMinMax(-2147483647,2147483647,N);
  116.   end; {ReadLongInt}
  117. {-----------------------------------------------------------------------------}
  118. { ReadByteMinMax, ReadIntgMinMax, and ReadLongIntMinMax read and display the
  119.   keyboard entry at the current cursor location until valid data (characters
  120.   (-,0-9,.,), range min to max) is entered.  If the data is not valid, the
  121.   entry is erased, warning sounded, and the cursor is positioned to the start
  122.   of the field.  Min and max are assumed to be valid corresponding bytes,
  123.   integers or longintegers.  If max is less than min, max and min are
  124.   swapped.  The Backspace, Delete, Left/Right Arrow, Home, End, and Esc keys
  125.   can be used to edit the data entry.  Enter terminates the data entry and does
  126.   not advance the cursor to the next line.  Example:  ReadIntgrMinMax(-5,5,N )
  127.   will return a valid integer number N in the range -5 to 5 from the keyboard.}
  128.  
  129. procedure ReadByteMinMax(Min,Max : byte; var N : byte);
  130.          { Requires procedure ReadLongIntMinMax }
  131.   var M : longint;
  132.   begin
  133.     ReadLongIntMinMax(Min,Max,M);
  134.     N := M;
  135.   end; {ReadByteMinMax}
  136.  
  137. procedure ReadIntgrMinMax(Min,Max : integer; var N : integer);
  138.          { Requires procedure ReadLongIntMinMax }
  139.   var M : longint;
  140.   begin
  141.     ReadLongIntMinMax(Min,Max,M);
  142.     N := M;
  143.   end; {ReadIntgrMinMax}
  144.  
  145. procedure ReadLongIntMinMax(Min,Max : longint; var N : longint);
  146.          { Requires procedure ErrorTone }
  147.   var
  148.     S             : string;
  149.     C             : char;
  150.     Error         : integer;
  151.     Temp          : longint;
  152.     I,X,Y         : byte;
  153.     OK            : boolean;
  154.   begin
  155.     X := WhereX; Y := WhereY;
  156.     if Min > Max then      {if min greater than max, swap min and max}
  157.       begin
  158.         Temp := Min;  Min := Max;  Max := Temp;
  159.       end;
  160.     repeat
  161.       S := '';  I := 0;
  162.       repeat
  163.         C := ReadKey;
  164.         case C of
  165.           '-','0'..'9': begin                      {-,0..9}
  166.                           if (X + I) < 80 then
  167.                             begin
  168.                               Inc(I);
  169.                               Insert(C,S,I);
  170.                               GotoXY(X+I-1,Y);
  171.                               Write(Copy(S,I,Length(S)-I+1));
  172.                               GotoXY(X+I,Y);
  173.                             end
  174.                           else ErrorTone; {Entry field cannot go beyond col 79}
  175.                         end;
  176.              #8       : begin                       {Backspace}
  177.                           Delete(S,I,1);
  178.                           if I > 0 then
  179.                             begin
  180.                               Dec(I);
  181.                               GotoXY(X,Y);
  182.                               Write(S,' ');
  183.                               GotoXY(X+I,Y);
  184.                             end
  185.                           else ErrorTone;
  186.                         end;
  187.             #13      : ;                            {CR}
  188.             #27      : begin                        {Escape}
  189.                          GotoXY(X,Y);
  190.                          for I := 1 to Length(S) do Write(' ');
  191.                          GotoXY(X,Y);
  192.                          S := ''; I := 0;
  193.                        end;
  194.             #0       : begin                      {Extended key}
  195.                          C := ReadKey;
  196.                          case C of
  197.                            #83 : begin                        {Delete}
  198.                                    if I <> Length(S) then
  199.                                      begin
  200.                                        Inc(I);
  201.                                        Delete(S,I,1);
  202.                                        GotoXY(X,Y);
  203.                                        Dec(I);
  204.                                        Write(S,' ');
  205.                                        GotoXY(X+I,Y);
  206.                                      end
  207.                                    else ErrorTone;
  208.                                  end;
  209.                            #75 : begin                        {Left Arrow}
  210.                                    if (X+I) > X then
  211.                                      begin
  212.                                        Dec(I);  GotoXY(X+I,Y);
  213.                                      end;
  214.                                  end;
  215.                            #77 : begin                        {Right Arrow}
  216.                                    if I < Length(S) then
  217.                                      begin
  218.                                      Inc(I);  GotoXY(X+I,Y);
  219.                                    end;
  220.                                  end;
  221.                            #71 : begin                        {Home}
  222.                                    GotoXY(X,Y);  I := 0;
  223.                                  end;
  224.                            #79 : begin                        {End}
  225.                                    GotoXY(X + Length(S),Y);
  226.                                    I := Length(S);
  227.                                  end;
  228.                          else ErrorTone;
  229.                        end;
  230.                      end;
  231.             else ErrorTone;
  232.         end;
  233.       until C = #13;                      {CR ends entry}
  234.       GotoXY(X,Y);
  235.       for I := 1 to Length(S) do Write(' ');
  236.       GotoXY(X,Y);
  237.       Val(S,N,Error);
  238.       if (Error = 0) and (N >= Min) and (N <= Max) then OK := True
  239.         else
  240.           begin
  241.             OK := False;
  242.             ErrorTone;
  243.           end;
  244.     until OK;
  245.     Write(N);
  246.   end {ReadLongIntMinMax};
  247. {-----------------------------------------------------------------------------}
  248. { ReadReal is similar to ReadRealMinMax except ReadReal accepts any valid
  249.   real number.  Example:  ReadReal(Num) will return only a valid real number. }
  250.  
  251. procedure ReadReal(var N : real);
  252.          { Requires procedure ReadRealMinMax }
  253.   begin
  254.     ReadRealMinMax(-9.999E37,9.999E37,N);
  255.   end; {ReadReal}
  256. {-----------------------------------------------------------------------------}
  257. { ReadRealMinMax reads and displays at the current location the keyboard entry
  258.   until a valid real number (characters (-,0-9,.,E,e), range min to max, up to
  259.   up to 11 digits in mantisa) is entered. Invalid keystrokes are ignored. If
  260.   the data is not valid, the entry is erased, warning sounded, and the cursor
  261.   is positioned to the start of the field.  Max must be greater than min. If
  262.   min is greater than max, then max and min are swapped.  The Backspace,
  263.   Delete, Left/Right Arrow, Home, End, and Esc keys can be used to edit the
  264.   data entry.  Enter terminates the data entry and does not advance the cursor
  265.   to the next line.  Example: ReadRealMinMax(10.0,15.0,Num) will return a valid
  266.   real number Num in the range 10 to 15 }
  267.  
  268. procedure ReadRealMinMax(Min,Max : real; var N : real);
  269.          { Requires procedure ErrorTone }
  270.   var
  271.     S              : string[80];
  272.     C              : char;
  273.     Error,Indx     : integer;
  274.     Temp           : real;
  275.     I,X,Y          : byte;
  276.     OK             : boolean;
  277.   begin
  278.     X := WhereX; Y := WhereY;
  279.     if Min > Max then      {if min greater than max, swap min and max}
  280.       begin
  281.         Temp := Min;  Min := Max;  Max := Temp;
  282.       end;
  283.     repeat
  284.     S := '';  I := 0;
  285.       repeat
  286.         C := ReadKey;
  287.         case C of
  288.           '-','.',
  289.           '0'..'9',
  290.           'E','e' : begin                      {-,.,0..9,E,e}
  291.                       if (X + I) < 80 then
  292.                         begin
  293.                           Inc(I);
  294.                           Insert(Upcase(C),S,I);
  295.                           GotoXY(X+I-1,Y);
  296.                           Write(Copy(S,I,Length(S)-I+1));
  297.                           GotoXY(X+I,Y);
  298.                         end
  299.                       else ErrorTone; {Entry field cannot go beyond col 79}
  300.                     end;
  301.            #8     : begin                       {Backspace}
  302.                       Delete(S,I,1);
  303.                       if I > 0 then
  304.                         begin
  305.                           Dec(I);
  306.                           GotoXY(X,Y);
  307.                           Write(S,' ');
  308.                           GotoXY(X+I,Y);
  309.                         end
  310.                       else ErrorTone;
  311.                     end;
  312.           #13     : ;                            {CR}
  313.           #27     : begin                        {Escape}
  314.                       GotoXY(X,Y);
  315.                       for I := 1 to Length(S) do Write(' ');
  316.                       GotoXY(X,Y);
  317.                       S := '';  I := 0;
  318.                     end;
  319.            #0     : begin                   {Extended key}
  320.                       C := ReadKey;
  321.                       case C of
  322.                         #83 : begin              {Delete}
  323.                                 if I <> Length(S) then
  324.                                   begin
  325.                                     Inc(I);
  326.                                     Delete(S,I,1);
  327.                                     GotoXY(X,Y);
  328.                                     Dec(I);
  329.                                     Write(S,' ');
  330.                                     GotoXY(X+I,Y);
  331.                                   end
  332.                                 else ErrorTone;
  333.                               end;
  334.                         #75 : begin                        {Left Arrow}
  335.                                 if (X+I) > X then
  336.                                   begin
  337.                                     Dec(I);  GotoXY(X+I,Y);
  338.                                   end;
  339.                               end;
  340.                         #77 : begin                        {Right Arrow}
  341.                                 if I < Length(S) then
  342.                                   begin
  343.                                     Inc(I);  GotoXY(X+I,Y);
  344.                                   end;
  345.                               end;
  346.                         #71 : begin                        {Home}
  347.                                 GotoXY(X,Y);  I := 0;
  348.                               end;
  349.                         #79 : begin                        {End}
  350.                                 GotoXY(X + Length(S),Y);
  351.                                 I := Length(S);
  352.                               end;
  353.                         else ErrorTone;
  354.                       end;
  355.                      end;
  356.                   else ErrorTone;
  357.                 end;
  358.       until C = #13;                      {CR ends entry}
  359.       if Pos('.',S)=1 then S:='0'+S;  {if only digits to right of DP entered}
  360.       GotoXY(X,Y);
  361.       for I := 1 to Length(S) do Write(' ');
  362.       GotoXY(X,Y);
  363.       Val(S,N,Error);
  364.       if (Error = 0) and (N >= Min) and (N <= Max) then OK := True
  365.         else
  366.           begin
  367.             OK := False;  ErrorTone;
  368.           end;
  369.     until OK;
  370.     Indx := Pos('E',S);                        {exponential notation}
  371.     if Indx > 0 then
  372.       begin
  373.         if N > 0 then Inc(Indx);                  {exponent positive}
  374.         Write(N:Indx+3);
  375.       end
  376.     else
  377.       begin
  378.         Indx := Pos('.',S);
  379.         if Indx > 0 then                       {fixed point notation}
  380.           Write(N:Length(S):Length(S)-Indx)  {fixed with dec pt}
  381.         else Write(N:Length(S):0);            {fixed, no dec pt}
  382.       end;
  383.   end {ReadRealMinMax};
  384. {-----------------------------------------------------------------------------}
  385. { ReadString reads a string of characters and echos the entered characters to
  386.   the display.  The Bksp, Del, Left/Right Arrow, Home, End, and Esc keys can
  387.   be used to edit the data entry.  Enter terminates the data entry and does
  388.   not advance the cursor to the next line.  The entered string must be on one
  389.   80 column line. Example: ReadString(Str) returns the keyboard entry for
  390.   string Str.  }
  391.  
  392. procedure ReadString(var S : string);
  393.          { Requires procedure ErrorTone }
  394.   var
  395.     C     : char;
  396.     I,X,Y : byte;
  397.   begin
  398.     S := '';  I := 0;
  399.     X := WhereX; Y := WhereY;
  400.     repeat
  401.       C := ReadKey;
  402.       case C of
  403.         #32..#127 : begin
  404.                       if (X + I) < 80 then
  405.                         begin
  406.                           Inc(I);
  407.                           Insert(C,S,I);
  408.                           GotoXY(X+I-1,Y);
  409.                           Write(Copy(S,I,Length(S)-I+1));
  410.                           GotoXY(X+I,Y);
  411.                         end
  412.                       else ErrorTone;     {Entry field cannot go beyond col 79}
  413.                     end;
  414.         #8        : begin                       {Backspace}
  415.                       Delete(S,I,1);
  416.                       if I > 0 then
  417.                         begin
  418.                           Dec(I);
  419.                           GotoXY(X,Y);
  420.                           Write(S,' ');
  421.                           GotoXY(X+I,Y);
  422.                         end
  423.                       else ErrorTone;
  424.                     end;
  425.         #13      : ;                            {CR}
  426.         #27      : begin                        {Escape}
  427.                      GotoXY(X,Y);
  428.                      for I := 1 to Length(S) do Write(' ');
  429.                      GotoXY(X,Y);
  430.                      S := '';  I := 0;
  431.                    end;
  432.          #0      : begin
  433.                      C := Readkey;
  434.                      case C of
  435.                        #83 : begin                        {Delete}
  436.                                if I <> Length(S) then
  437.                                  begin
  438.                                    Inc(I);
  439.                                    Delete(S,I,1);
  440.                                    GotoXY(X,Y);
  441.                                    Dec(I);
  442.                                    Write(S,' ');
  443.                                    GotoXY(X+I,Y);
  444.                                  end
  445.                                else ErrorTone;
  446.                              end;
  447.                        #75 : begin                      {Left Arrow}
  448.                                if (X+I) > X then
  449.                                  begin
  450.                                    Dec(I);  GotoXY(X+I,Y);
  451.                                  end;
  452.                              end;
  453.                        #77 : begin                      {Right Arrow}
  454.                                if I < Length(S) then
  455.                                begin
  456.                                  Inc(I);  GotoXY(X+I,Y);
  457.                                end;
  458.                              end;
  459.                        #71 : begin                         {Home}
  460.                                GotoXY(X,Y);  I := 0;
  461.                              end;
  462.                        #79 : begin                         {End}
  463.                                GotoXY(X + Length(S),Y);
  464.                                I := Length(S);
  465.                              end;
  466.                         else ErrorTone;
  467.                      end;
  468.                   end;
  469.          else ErrorTone;
  470.       end;
  471.     until C = #13;
  472.   end {ReadString};
  473. {-----------------------------------------------------------------------------}
  474.  
  475. begin
  476.   ErrorToneEnb := True;                             { Enable ErrorTone }
  477. end.
  478.